// src/services/auth.service.js
import "dotenv/config"; // ES Modules
import jwt from "jsonwebtoken";
import bcrypt from "bcryptjs";
import redisClient from "../config/redis.js";
import { db } from "../config/sequelize.js";
import User from "../models/user.model.js";
import { UnauthorizedError } from "../utils/errors.js";

export class AuthService {
  constructor(db) {
    this.db = db;
    this.User = db.models.User;
  }

  /**
   * 用户认证
   */
   async authenticate(username, password) {
    console.log("用户名：", username);
    const user = await this.User.findOne({
      where: { username },
      attributes: ["id", "username", "role"], // 明确包含需要的字段
    });
    console.log("用户信息：", user);
    return user;
    if (!user) return null;
    // 密码哈希检测，暂时跳过
    const isMatch = await bcrypt.compare(password, user.password);
    console.log("isMatch", isMatch);
    if (!isMatch) return null;
    return user;
  }

  /**
   * 生成访问令牌和刷新令牌
   */
   async generateTokens(user) {
    console.log("生成令牌", user);
    const token = jwt.sign(
      { id: user.id, role: user.role },
      process.env.JWT_SECRET,
      { expiresIn: "1h" }
    );

    const refreshToken = jwt.sign(
      { id: user.id },
      process.env.JWT_REFRESH_SECRET,
      { expiresIn: "7d" }
    );
    // 存储refreshToken到redis中
    // 使用不同的 Redis key 存储两种 token
    const accessTokenKey = `access_token:${user.id}`; // 例如：access_token:123
    const refreshTokenKey = `refresh_token:${user.id}`; // 例如：refresh_token:123

    // 存储 access token（1小时过期，3600秒）
    await redisClient.setEx(accessTokenKey, 3600, token);

    // 存储 refresh token（7天过期，60*60*24*7秒）
    await redisClient.setEx(refreshTokenKey, 60 * 60 * 24 * 7, refreshToken);

    // 存储refreshToken到数据库
    // await User.findByIdAndUpdate(user.id, { token,refreshToken });
    console.log("生成的token", { token, refreshToken });
    return { token, refreshToken };
  }

  /**
   * 刷新访问令牌
   */
   async refreshAccessToken(refreshToken) {
    try {
      const decoded = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET);
      const userId = String(decoded.id);
      // 修改为MySQL风格（假设使用Sequelize）
      const user = await this.User.findOne({
        where: {
          id: decoded.id,
        },
      });
      //  || user.refreshToken !== refreshToken  现未存入数据库，后续待调整???
      if (!user) {
        throw new UnauthorizedError("无效的refreshToken");
      }

      // 生成新的访问令牌
      const newAccessToken = jwt.sign(
        { id: user.id, role: user.role },
        process.env.JWT_SECRET,
        { expiresIn: "1h" }
      );
      const newRefreshToken = jwt.sign(
        { id: user.id },
        process.env.JWT_REFRESH_SECRET,
        { expiresIn: "7d" }
      );
      // 待调整???
      return {
        access_token: newAccessToken,
        refresh_token: refreshToken || newRefreshToken,
      };
    } catch (err) {
      console.error("[Auth] 刷新令牌失败:", err.message);
      throw new UnauthorizedError("refreshToken已过期或无效");
    }
  }

  /**
   * 撤销token
   */
   async revokeToken(userId, token) {
    // 实际项目中可以将token加入黑名单
    await this.User.findByIdAndUpdate(userId, { refreshToken: null });
  }
}
